﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;

namespace HostAssistantCore
{







    /// <summary>    /// Xml的操作公共类    /// </summary>        public class XmlHelper    {









        #region 字段定义        /// <summary>                             /// XML文件的物理路径                             /// </summary>        private string _filePath = string.Empty;












        /// <summary>        /// Xml文档        /// </summary>        private XmlDocument _xml;












        /// <summary>        /// XML的根节点        /// </summary>        private XmlElement _element;
























        #endregion
        #region 构造方法        /// <summary>                             /// 实例化XmlHelper对象                             /// </summary>                             /// <param name="xmlFilePath">Xml文件的相对路径</param>        public XmlHelper(string xmlFilePath)        {
            //获取XML文件的绝对路径
            _filePath = xmlFilePath;        }




















        #endregion
        #region 创建XML的根节点        /// <summary>                                  /// 创建XML的根节点                                  /// </summary>        private void CreateXMLElement()        {

            //创建一个XML对象
            _xml = new XmlDocument();

            if (System.IO.File.Exists(_filePath))            {
                //加载XML文件
                _xml.Load(this._filePath);            }

            //为XML的根节点赋值
            _element = _xml.DocumentElement;        }








































        #endregion
        #region 获取指定XPath表达式的节点对象        /// <summary>                                          /// 获取指定XPath表达式的节点对象                                          /// </summary>                                                  /// <param name="xPath">XPath表达式,                                          /// 范例1: @"Skill/First/SkillItem", 等效于 @"//Skill/First/SkillItem"                                          /// 范例2: @"Table[USERNAME='a']" , []表示筛选,USERNAME是Table下的一个子节点.                                          /// 范例3: @"ApplyPost/Item[@itemName='岗位编号']",@itemName是Item节点的属性.                                          /// </param>        public XmlNode GetNode(string xPath)        {
            try
            {
                //创建XML的根节点
                CreateXMLElement();

                //返回XPath节点
                return _element.SelectSingleNode(xPath);
            }
            catch
            {
                return null;
            }        }








































        #endregion
        #region 获取指定XPath表达式节点的值        /// <summary>                                         /// 获取指定XPath表达式节点的值                                         /// </summary>                                         /// <param name="xPath">XPath表达式,                                         /// 范例1: @"Skill/First/SkillItem", 等效于 @"//Skill/First/SkillItem"                                         /// 范例2: @"Table[USERNAME='a']" , []表示筛选,USERNAME是Table下的一个子节点.                                         /// 范例3: @"ApplyPost/Item[@itemName='岗位编号']",@itemName是Item节点的属性.                                         /// </param>        public string GetValue(string xPath)        {
            //创建XML的根节点
            CreateXMLElement();

            //返回XPath节点的值
            return _element.SelectSingleNode(xPath).InnerText;        }












































        #endregion
        #region 获取指定XPath表达式节点的属性值        /// <summary>                                           /// 获取指定XPath表达式节点的属性值                                           /// </summary>                                           /// <param name="xPath">XPath表达式,                                           /// 范例1: @"Skill/First/SkillItem", 等效于 @"//Skill/First/SkillItem"                                           /// 范例2: @"Table[USERNAME='a']" , []表示筛选,USERNAME是Table下的一个子节点.                                           /// 范例3: @"ApplyPost/Item[@itemName='岗位编号']",@itemName是Item节点的属性.                                           /// </param>                                           /// <param name="attributeName">属性名</param>        public string GetAttributeValue(string xPath, string attributeName)        {
            try
            {
                //创建XML的根节点
                CreateXMLElement();

                //返回XPath节点的属性值
                return _element.SelectSingleNode(xPath).Attributes[attributeName].Value;
            }
            catch
            {
                return null;
            }        }




























        #endregion
        #region 新增节点        /// <summary>                             /// 1. 功能：新增节点。                             /// 2. 使用条件：将任意节点插入到当前Xml文件中。                             /// </summary>                                     /// <param name="xmlNode">要插入的Xml节点</param>        public void AppendNode(XmlNode xmlNode)        {
            //创建XML的根节点
            CreateXMLElement();

            //导入节点
            XmlNode node = _xml.ImportNode(xmlNode, true);

            //将节点插入到根节点下
            _element.AppendChild(node);        }

        #endregion

        #region 在指定节点下添加子节点
        /// <summary>
        /// 根据xpath找到父节点 添加subnode
        /// </summary>
        /// <param name="xpath"></param>
        /// <param name="subnode"></param>
        public bool AppendSubNode(string xpath, string nodename)
        {
            try
            {
                //创建XML的根节点
                CreateXMLElement();
                //查找父节点
                XmlNode parentnode = _xml.SelectSingleNode(xpath);
                XmlElement subnode = _xml.CreateElement(nodename);//创建一个具有指定名称的子节点
                parentnode.AppendChild(subnode);
                //_element.AppendChild(parentnode);
                //保存XML文件
                _xml.Save(this._filePath);
                return true;
            }
            catch
            {
                return false;
            }
        }
        /// <summary>
        /// 根据xpath找到父节点 添加subnode 并添加所有属性
        /// </summary>
        /// <param name="xpath"></param>
        /// <param name="subnode"></param>
        public bool AppendSubNode_Q(string xpath, Dictionary<string, string> rule)
        {
            try
            {
                //创建XML的根节点
                CreateXMLElement();
                //查找父节点
                XmlNode parentnode = _xml.SelectSingleNode(xpath);
                /*---- attributes ---*/
                foreach (string tag in rule.Keys)
                {
                    XmlAttribute subattr = _xml.CreateAttribute(tag);
                    subattr.Value = rule[tag];
                    parentnode.Attributes.Append(subattr);
                }
                //_element.AppendChild(parentnode);
                //保存XML文件
                _xml.Save(this._filePath);
                return true;
            }
            catch
            {
                return false;
            }
        }
        #endregion    

        #region 往节点添加内容
        /// <summary>
        /// 根据xpath找到父节点 添加Text
        /// </summary>
        /// <param name="xpath"></param>
        /// <param name="text"></param>
        /// <returns></returns>
        public bool AppendNodeText(string xpath, string text)
        {
            try
            {
                //创建XML的根节点
                CreateXMLElement();
                //查找节点
                XmlNode node = _xml.SelectSingleNode(xpath);
                //添加内容
                node.InnerXml = node.InnerXml + text;//创建一个具有指定名称的子节点
                //保存XML文件
                _xml.Save(this._filePath);
                return true;
            }
            catch
            {
                return false;
            }
        }
































        #endregion

        #region 删除节点
        /// <summary>        /// 删除指定XPath表达式的节点        /// </summary>                /// <param name="xPath">XPath表达式,        /// 范例1: @"Skill/First/SkillItem", 等效于 @"//Skill/First/SkillItem"        /// 范例2: @"Table[USERNAME='a']" , []表示筛选,USERNAME是Table下的一个子节点.        /// 范例3: @"ApplyPost/Item[@itemName='岗位编号']",@itemName是Item节点的属性.        /// </param>        public void RemoveNode(string xPath)        {
            //创建XML的根节点
            CreateXMLElement();

            //获取要删除的节点
            XmlNode node = _xml.SelectSingleNode(xPath);

            //删除节点
            _element.RemoveChild(node);        }        #endregion //删除节点

        #region 删除Xpath下所有节点
        /// <summary>
        /// 删除指定XPath表达式的节点
        /// </summary>        
        /// <param name="xPath">XPath表达式,
        /// 范例1: @"Skill/First/SkillItem", 等效于 @"//Skill/First/SkillItem"
        /// 范例2: @"Table[USERNAME='a']" , []表示筛选,USERNAME是Table下的一个子节点.
        /// 范例3: @"ApplyPost/Item[@itemName='岗位编号']",@itemName是Item节点的属性.
        /// </param>
        public void RemoveAllNodes(string parent_Xpath, string son_Xpath)
        {
            //创建XML的根节点
            CreateXMLElement();

            //获取要删除的节点
            XmlNode xpath = _xml.SelectSingleNode(parent_Xpath);
            XmlNodeList nodes = xpath.SelectNodes(son_Xpath);

            //删除节点
            foreach (XmlNode node in nodes)
            {
                xpath.RemoveChild(node);
            }
            //保存XML文件
            _xml.Save(this._filePath);
        }




















        #endregion //删除节点
        #region 保存XML文件        /// <summary>                                /// 保存XML文件                                /// </summary>                public void Save()        {
            //创建XML的根节点
            CreateXMLElement();

            //保存XML文件
            _xml.Save(this._filePath);        }




























        #endregion //保存XML文件
        #region 静态方法
        #region 创建根节点对象        /// <summary>                                /// 创建根节点对象                                /// </summary>                                /// <param name="xmlFilePath">Xml文件的相对路径</param>                private static XmlElement CreateRootElement(string xmlFilePath)        {
            //定义变量，表示XML文件的绝对路径
            string filePath = "";

            //获取XML文件的绝对路径
            filePath = xmlFilePath;

            //创建XmlDocument对象
            XmlDocument xmlDocument = new XmlDocument();
            //加载XML文件
            xmlDocument.Load(filePath);

            //返回根节点
            return xmlDocument.DocumentElement;        }
        private static XmlElement CreateRootElementFromString(string xmlDoc)
        {
            //创建XmlDocument对象
            XmlDocument xmlDocument = new XmlDocument();
            //加载XML文件
            xmlDocument.LoadXml(xmlDoc);

            //返回根节点
            return xmlDocument.DocumentElement;
        }












































        #endregion
        #region 获取指定XPath表达式节点的值        /// <summary>                                         /// 获取指定XPath表达式节点的值                                         /// </summary>                                         /// <param name="xmlFilePath">Xml文件的相对路径</param>                                         /// <param name="xPath">XPath表达式,                                         /// 范例1: @"Skill/First/SkillItem", 等效于 @"//Skill/First/SkillItem"                                         /// 范例2: @"Table[USERNAME='a']" , []表示筛选,USERNAME是Table下的一个子节点.                                         /// 范例3: @"ApplyPost/Item[@itemName='岗位编号']",@itemName是Item节点的属性.                                         /// </param>        public static string GetValue(string xmlFilePath, string xPath)        {
            //创建根对象
            XmlElement rootElement = CreateRootElement(xmlFilePath);

            //返回XPath节点的值
            return rootElement.SelectSingleNode(xPath).InnerText;        }
        public static string GetValueFromString(string xmlDoc, string xPath)
        {
            //创建根对象
            XmlElement rootElement = CreateRootElementFromString(xmlDoc);

            //返回XPath节点的值
            return rootElement.SelectSingleNode(xPath).InnerText;
        }








































        #endregion

        #region 获取指定XPath表达式节点的属性值
        /// <summary>        /// 获取指定XPath表达式节点的属性值        /// </summary>        /// <param name="xmlFilePath">Xml文件的相对路径</param>        /// <param name="xPath">XPath表达式,        /// 范例1: @"Skill/First/SkillItem", 等效于 @"//Skill/First/SkillItem"        /// 范例2: @"Table[USERNAME='a']" , []表示筛选,USERNAME是Table下的一个子节点.        /// 范例3: @"ApplyPost/Item[@itemName='岗位编号']",@itemName是Item节点的属性.        /// </param>        /// <param name="attributeName">属性名</param>        public static string GetAttributeValue(string xmlFilePath, string xPath, string attributeName)        {
            //创建根对象
            XmlElement rootElement = CreateRootElement(xmlFilePath);

            //返回XPath节点的属性值
            return rootElement.SelectSingleNode(xPath).Attributes[attributeName].Value;        }




        #endregion
        #endregion
        public static void SetValue(string xmlFilePath, string xPath, string newtext)        {
            //string path = SysHelper.GetPath(xmlFilePath);
            //var queryXML = from xmlLog in xelem.Descendants("msg_log")
            //               //所有名字为Bin的记录
            //               where xmlLog.Element("user").Value == "Bin"
            //               select xmlLog;

            //foreach (XElement el in queryXML)
            //{
            //    el.Element("user").Value = "LiuBin";//开始修改
            //}
            //xelem.Save(path);
        }    }
}
